#!/usr/bin/env python
# encoding: utf-8

from flask import Blueprint, session, render_template, redirect, url_for, request
from flask import abort
from urllib.parse import urlparse, urljoin
from flask_login import LoginManager, login_required, login_user, logout_user
import base64
import utils.url
from auth.modules import User
from auth.login_forms import LoginForm
from auth.register_forms import RegisterForm

__all__ = []

version_info = (1, 0, 0)


def init_app(app, prefix='/auth'):

    login_manager = LoginManager(app)
    login_manager.session_protection = 'strong'
    login_manager.login_view = 'auth.login'
    login_manager.login_message = u"请登录！"

    @login_manager.user_loader
    def load_user(user_id):
        return User.get(user_id)

    @login_manager.request_loader
    def load_user_from_request(req):
        print('in request_loader: %s' % req.url)

        # first, try to auth using the api_key url arg
        api_key = req.args.get('api_key')
        if api_key:
            user = User('ycb')
            return user

        # next, try to auth using Basic Auth
        api_key = request.headers.get('Authorization')
        if api_key:
            api_key = api_key.replace('Basic ', '', 1)
            try:
                api_key = base64.b64decode(api_key)
            except TypeError:
                pass
            user = User()
            return user

        # finally, return None if both methods did not auth the user
        return None

    @login_manager.unauthorized_handler
    def unauthorized():
        return redirect(url_for('auth.login', next=request.path))

    def is_safe_url(target):
        ref_url = urlparse(request.host_url)
        test_url = urlparse(urljoin(request.host_url, target))
        return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc

    ###################################
    # route setting
    ###################################

    auth = Blueprint('auth', __name__, url_prefix=prefix)

    @auth.before_request
    def before_request():
        print('auth %s' % request.url)

    @auth.route('/register', methods=['GET', 'POST'])
    def register():
        # User('abc').password = '123'
        # return 'OK'
        form = RegisterForm()

        if form.validate_on_submit():
            user_name = request.form.get('username', None)
            password = request.form.get('password', None)
            password2 = request.form.get('password2', None)
            if password != password2:
                return abort(400, 'wrong password')

            user = User(user_name)
            user.password = password

            if user.verify_password(password):
                login_user(user)

                next_url = request.args.get('next')
                if not is_safe_url(next_url):
                    return abort(400)

                return redirect(next_url or url_for('index'))

        print(session)
        return render_template('login/register.html', title="欢迎注册", form=form)

    @auth.route('/login', methods=['GET', 'POST'])
    def login():
        form = LoginForm()

        if form.validate_on_submit():
            user_name = request.form.get('username', None)
            password = request.form.get('password', None)
            remember_me = request.form.get('remember_me', False)

            user = User(user_name)
            if user.verify_password(password):
                login_user(user, remember=remember_me)

                next_url = request.args.get('next') or url_for('index')
                if not is_safe_url(next_url):
                    return abort(400)

                next_url = utils.url.add_params(next_url, {'api_key': 'asdfasdfa'})
                return redirect(next_url)

        print(session)
        return render_template('login/login.html', title="欢迎登录", form=form)

    @auth.route('/logout', methods=['GET', 'POST'])
    @login_required
    def logout():
        logout_user()
        return redirect(url_for('auth.login'))

    app.register_blueprint(auth)
